import axios, {
  AxiosError,
  AxiosRequestConfig,
  AxiosResponse,
  Canceler,
  CancelTokenStatic
} from "axios";

const request = axios.create({
  timeout: 1000 * 5,
  baseURL: "/f"
});

const pending: Array<string | undefined> = [];
const cancelPending = (config: AxiosRequestConfig, f?: Canceler): void => {
  const flagUrl = config.url;
  if (!config) return;
  if (pending.indexOf(flagUrl) > -1) {
    // 如果在请求中，并存在f,f即axios提供的取消函数
    if (f) {
      f("取消重复请求");
    } else {
      pending.splice(pending.indexOf(flagUrl), 1);
    }
  } else {
    // 如果不存在在请求队列中，加入队列
    if (f) {
      pending.push(flagUrl);
    }
  }
};

const CancelToken: CancelTokenStatic = axios.CancelToken;

request.interceptors.request.use(
  (config: AxiosRequestConfig): AxiosRequestConfig => {
    config.cancelToken = new CancelToken((cancel: Canceler) => {
      cancelPending(config, cancel);
    });
    return config;
  },
  (error: AxiosError): void => {
    Promise.reject(error);
  }
);

request.interceptors.response.use(
  (response: AxiosResponse): AxiosResponse => {
    cancelPending(response.config);
    return response;
  },
  (err: AxiosError) => {
    if (err && err.response) {
      switch (err.response.status) {
        case 400:
          err.message = "错误请求";
          break;
        case 401:
          err.message = "未授权，请重新登录";
          break;
        case 403:
          err.message = "拒绝访问";
          break;
        case 404:
          err.message = "请求错误,未找到该资源";
          break;
        case 405:
          err.message = "请求方法未允许";
          break;
        case 408:
          err.message = "请求超时";
          break;
        case 500:
          err.message = "服务器端出错";
          break;
        case 501:
          err.message = "网络未实现";
          break;
        case 502:
          err.message = "网络错误";
          break;
        case 503:
          err.message = "服务不可用";
          break;
        case 504:
          err.message = "网络超时";
          break;
        case 505:
          err.message = "http版本不支持该请求";
          break;
        default:
          err.message = `连接错误${err.response.status}`;
      }
      return Promise.reject(err);
    }
  }
);

export default request;
